package org.noote.libs.computervision.detection.line;

import java.util.ArrayList;
import java.util.List;

import org.noote.libs.computervision.buffer.Buffer8888XRGB;

public class LineDetection_MergeSegments extends LineDetection_RANSAC {

	protected static final float _mergesegments_colinear_distance = _ransac_step*0.25f;
	protected static final float _mergesegments_distance = _ransac_step;
	protected static final boolean _mergesegments_expand = false;
	
	// for stats
	public long _stat_duration = 0, _stat_sobel = 0, _stat_ransac = 0, _stat_merge = 0;

	// liste
	public List<OrientedSegment> _allmergedsegments = new ArrayList<OrientedSegment>();
	
	// merge les segments
	void merge_segments()
	{
		// merge all wild segments in final segments ^^
		_allmergedsegments.clear();
		for(OrientedSegment rs : _allransacsegments)
		{
			OrientedSegment s = new OrientedSegment(rs.start, rs.end);
			_allmergedsegments.add(s);
		}

		while(true)
		{
			boolean havemerged = false;
			for(OrientedSegment s1 : _allmergedsegments)
			{
				for(OrientedSegment s2 : _allmergedsegments)
				{
					if(s1 != s2)
					{
						if(s1.isMergeable(s2, _mergesegments_colinear_distance, _mergesegments_distance))
						{
							s1.merge(s2);
							_allmergedsegments.remove(s2);
							havemerged = true;
							break;
						}
					}
				}
				// ok have a modification... so rebuild
				if(havemerged)
					break;
			}
			// nothing ? so quit
			if(!havemerged)
				break;
		}
		
		if(_mergesegments_expand)
		{
			for(OrientedSegment s: _allmergedsegments)
			{
				s.expand(_ransac_block);
			}
		}
	}

	public void clearTime()
	{
		_stat_sobel = _stat_ransac = _stat_merge = _stat_duration = 0;
	}
	public void detect(Buffer8888XRGB xrgb)
	{
		long begin = System.currentTimeMillis();
		
		// do sobel filter (3x3)
		do3x3(xrgb, _sobel_limit_min);
		_stat_sobel = System.currentTimeMillis() - (begin);
		
		// ransac
		calcul_ransac();
		_stat_ransac = System.currentTimeMillis() - (begin + _stat_sobel);

		// merge segments
		merge_segments();
		_stat_merge = System.currentTimeMillis() - (begin + _stat_sobel + _stat_ransac);
		
		_stat_duration = System.currentTimeMillis() - begin;		
	}
}
